package com.javacoo.fastdfs.client.api.client;

import java.util.Map;
import java.util.Optional;

import org.csource.common.NameValuePair;
import org.csource.fastdfs.DownloadCallback;
import org.csource.fastdfs.FileInfo;
import org.csource.fastdfs.UploadCallback;

import com.javacoo.fastdfs.client.api.template.FastDFSTemplate;
import com.javacoo.fastdfs.client.exception.JccfcFastDFSException;

/**
 * FastDFSClient
 * <p>说明:</p>
 * <li>基于org.csource.fastdfs.StorageClient1 1.27.0.0</li>
 * @author duanyong@jccfc.com
 * @data 2020/5/1 21:42
 */
public interface FastDFSClient {
    /**
     * 初始化
     * <p>说明:</p>
     * <li></li>
     * @author duanyong@jccfc.com
     * @date 2020/5/3 15:55
     * @param fastDFSTemplate FastDFS操作模板接口
     * @return FastDFSClient
     */
    FastDFSClient init(FastDFSTemplate fastDFSTemplate);

    /**
     * 上传文件到存储服务器(按文件名)
     *
     * @param localFileName 待上传的本地文件名称
     * @param fileExtName  文件类型名称，不包含点(.)，如果为空则从localFileName提取
     * @param metaList      元数据数组
     * @return 如果成功，返回文件id(包括组名和文件名), <br>
     * 失败返回null
     */
    Optional<String> uploadFile(String localFileName, String fileExtName, NameValuePair[] metaList) throws JccfcFastDFSException;

    /**
     * 上传文件到存储服务器(按文件名)
     *
     * @param groupName     要上传文件的组名，可以为空
     * @param localFileName 待上传的本地文件名称
     * @param fileExtName  文件类型名称，不包含点(.)，如果为空则从localFileName提取
     * @param metaList      元数据数组
     * @return 如果成功，返回文件id(包括组名和文件名), <br>
     * 失败返回null
     */
    Optional<String> uploadFile(String groupName, String localFileName, String fileExtName,NameValuePair[] metaList) throws JccfcFastDFSException;

    /**
     * 上传文件到存储服务器(按文件字节数组)
     *
     * @param fileBuff     文件内容字节数组
     * @param fileExtName 文件扩展名，不包含(.)
     * @return 如果成功，返回文件id(包括组名和文件名), <br>
     * 失败返回null
     */
    Optional<String> uploadFile(byte[] fileBuff, String fileExtName) throws JccfcFastDFSException;

    /**
     * 上传文件到存储服务器(按文件字节数组)
     *
     * @param fileBuff     文件内容字节数组
     * @param fileExtName 文件扩展名，不包含(.)
     * @param metaMap     元数据数组
     * @return 如果成功，返回文件id(包括组名和文件名), <br>
     * 失败返回null
     */
    Optional<String> uploadFile(byte[] fileBuff, String fileExtName, Map<String, String> metaMap) throws JccfcFastDFSException;

    /**
     * 上传文件到存储服务器(按文件字节数组)
     *
     * @param fileBuff     文件内容字节数组
     * @param fileExtName 文件扩展名，不包含(.)
     * @param metaList     元数据数组
     * @return 如果成功，返回文件id(包括组名和文件名), <br>
     * 失败返回null
     */
    Optional<String> uploadFile(byte[] fileBuff, String fileExtName,NameValuePair[] metaList) throws JccfcFastDFSException;

    /**
     * 上传文件到存储服务器(按文件字节数组)
     *
     * @param groupName    要上传文件的组名，可以为空
     * @param fileBuff     文件内容字节数组
     * @param fileExtName 文件扩展名，不包含(.)
     * @param metaList     元数据数组
     * @return 如果成功，返回文件id(包括组名和文件名), <br>
     * 失败返回null
     */
    Optional<String> uploadFile(String groupName, byte[] fileBuff, String fileExtName,NameValuePair[] metaList) throws JccfcFastDFSException;

    /**
     * 上传文件到存储服务器(按回调)
     *
     * @param groupName    要上传文件的组名，可以为空
     * @param fileSize     文件大小
     * @param callback      写数据回调对象
     * @param fileExtName 文件扩展名，不包含(.)
     * @param metaList     元数据数组
     * @return 如果成功，返回文件id(包括组名和文件名), <br>
     * 失败返回null
     */
    Optional<String> uploadFile(String groupName, long fileSize,UploadCallback callback, String fileExtName,NameValuePair[] metaList) throws JccfcFastDFSException;

    /**
     * 上传附加文件到存储服务器(按文件名)
     *
     * @param localFileName 待上传的本地文件名称
     * @param fileExtName  文件类型名称，不包含点(.)，如果为空则从localFileName提取
     * @param metaList      元数据数组
     * @return 如果成功，返回文件id(包括组名和文件名), <br>
     * 失败返回null
     */
    Optional<String> uploadAppenderFile(String localFileName, String fileExtName,NameValuePair[] metaList) throws JccfcFastDFSException;

    /**
     * 上传附加文件到存储服务器(按文件名)
     *
     * @param groupName     要上传文件的组名，可以为空
     * @param localFileName 待上传的本地文件名称
     * @param fileExtName  文件类型名称，不包含点(.)，如果为空则从localFileName提取
     * @param metaList      元数据数组
     * @return 如果成功，返回文件id(包括组名和文件名), <br>
     * 失败返回null
     */
    Optional<String> uploadAppenderFile(String groupName, String localFileName, String fileExtName,NameValuePair[] metaList) throws JccfcFastDFSException;

    /**
     * 上传附加文件到存储服务器(按文件字节数组)
     *
     * @param fileBuff     文件内容字节数组
     * @param fileExtName 文件扩展名，不包含(.)
     * @param metaList     元数据数组
     * @return 如果成功，返回文件id(包括组名和文件名), <br>
     * 失败返回null
     */
    Optional<String> uploadAppenderFile(byte[] fileBuff, String fileExtName,NameValuePair[] metaList) throws JccfcFastDFSException;

    /**
     * 上传附加文件到存储服务器(按文件字节数组)
     *
     * @param groupName    要上传文件的组名，可以为空
     * @param fileBuff     文件内容字节数组
     * @param fileExtName 文件扩展名，不包含(.)
     * @param metaList     元数据数组
     * @return 如果成功，返回文件id(包括组名和文件名), <br>
     * 失败返回null
     */
    Optional<String> uploadAppenderFile(String groupName, byte[] fileBuff, String fileExtName,NameValuePair[] metaList) throws JccfcFastDFSException;

    /**
     * 上传附加文件到存储服务器(通过回调)
     *
     * @param groupName    要上传文件的组名，可以为空
     * @param fileSize     文件大小
     * @param callback      写数据回调对象
     * @param fileExtName 文件扩展名，不包含(.)
     * @param metaList     元数据数组
     * @return 如果成功，返回文件id(包括组名和文件名), <br>
     * 失败返回null
     */
    Optional<String> uploadAppenderFile(String groupName, long fileSize,UploadCallback callback, String fileExtName,NameValuePair[] metaList) throws JccfcFastDFSException;

    /**
     * 上传文件到存储服务器(按文件名，从文件)
     *
     * @param masterFileId 文件id来生成从文件
     * @param prefixName    用来生成从属文件的前缀名
     * @param localFileName 待上传的本地文件名称
     * @param fileExtName  文件类型名称，不包含点(.)，如果为空则从localFileName提取
     * @param metaList      元数据数组
     * @return 如果成功，返回文件id(包括组名和文件名), <br>
     * 失败返回null
     */
    Optional<String> uploadFile(String masterFileId, String prefixName,String localFileName, String fileExtName, NameValuePair[] metaList) throws JccfcFastDFSException;

    /**
     * 上传文件到存储服务器(按文件增益，从文件)
     *
     * @param masterFileId 主文件id来生成从文件
     * @param prefixName    用来生成从属文件的前缀名
     * @param fileBuff      文件内容字节数组
     * @param fileExtName  文件扩展名，不包含(.)
     * @param metaList      元数据数组
     * @return 如果成功，返回文件id(包括组名和文件名), <br>
     * 失败返回null
     */
    Optional<String> uploadFile(String masterFileId, String prefixName,byte[] fileBuff, String fileExtName, NameValuePair[] metaList) throws JccfcFastDFSException;

    /**
     * 上传文件到存储服务器(按文件增益，从文件)
     *
     * @param masterFileId 主文件id来生成从文件
     * @param prefixName    用来生成从属文件的前缀名
     * @param fileBuff      文件内容字节数组
     * @param fileExtName  文件扩展名，不包含(.)
     * @param metaList      元数据数组
     * @return 如果成功，返回文件id(包括组名和文件名), <br>
     * 失败返回null
     */
    Optional<String> uploadFile(String masterFileId, String prefixName,byte[] fileBuff, int offset, int length, String fileExtName,NameValuePair[] metaList) throws JccfcFastDFSException;
    /**
     * 上传文件到存储服务器(通过回调)
     *
     * @param masterFileId 主文件id来生成从文件
     * @param prefixName    用来生成从属文件的前缀名
     * @param fileSize      文件大小
     * @param callback       写数据回调对象
     * @param fileExtName  文件扩展名，不包含(.)
     * @param metaList      元数据数组
     * @return 如果成功，返回文件id(包括组名和文件名), <br>
     * 失败返回null
     */
    Optional<String> uploadFile(String masterFileId, String prefixName, long fileSize,UploadCallback callback, String fileExtName,NameValuePair[] metaList) throws JccfcFastDFSException;

    /**
     * 将文件附加到存储服务器(按文件名)
     *
     * @param appenderFileId 附加文件id
     * @param localFileName   要附加的本地文件名
     * @return 0表示成功，!= 0表示错误(错误号)
     */
    public Optional<Integer> appendFile(String appenderFileId, String localFileName) throws JccfcFastDFSException;

    /**
     * 将文件附加到存储服务器(按文件字节数组)
     *
     * @param appenderFileId 附加文件id
     * @param fileBuff        文件内容字节数组
     * @return 0表示成功，!= 0表示错误(错误号)
     */
    Optional<Integer> appendFile(String appenderFileId, byte[] fileBuff) throws JccfcFastDFSException;

    /**
     * 将文件附加到存储服务器(按文件字节数组)
     *
     * @param appenderFileId 附加文件id
     * @param fileBuff        文件内容字节数组er
     * @param offset           缓冲区的起始偏移量
     * @param length           要追加的缓冲区的长度
     * @return 0表示成功，!= 0表示错误(错误号)
     */
    Optional<Integer> appendFile(String appenderFileId, byte[] fileBuff, int offset, int length) throws JccfcFastDFSException;

    /**
     * 将文件追加到存储服务器(通过回调)
     *
     * @param appenderFileId 附加文件id
     * @param fileSize        文件大小
     * @param callback         写数据回调对象
     * @return 0表示成功，!= 0表示错误(错误号)
     */
    Optional<Integer> appendFile(String appenderFileId, long fileSize, UploadCallback callback) throws JccfcFastDFSException;

    /**
     * 修改存储服务器的附加文件 (文件名)
     *
     * @param appenderFileId 附加文件id
     * @param fileOffset      附加文件的偏移量
     * @param localFileName   要附加的本地文件名
     * @return 0表示成功，!= 0表示错误(错误号)
     */
    Optional<Integer> modifyFile(String appenderFileId,long fileOffset, String localFileName) throws JccfcFastDFSException;

    /**
     * 修改存储服务器的附加文件 (字节数组)
     *
     * @param appenderFileId 附加文件id
     * @param fileOffset      附加文件的偏移量
     * @param fileBuff        文件内容字节数组
     * @return 0表示成功，!= 0表示错误(错误号)
     */
    Optional<Integer> modifyFile(String appenderFileId,long fileOffset, byte[] fileBuff) throws JccfcFastDFSException;

    /**
     * 修改存储服务器的附加文件 (字节数组)
     *
     * @param appenderFileId 附加文件id
     * @param fileOffset      附加文件的偏移量
     * @param fileBuff        文件内容字节数组
     * @param bufferOffset    字节数组起始偏移量
     * @param bufferLength    修改的字节数组长度
     * @return 0表示成功，!= 0表示错误(错误号)
     */
    Optional<Integer> modifyFile(String appenderFileId,long fileOffset, byte[] fileBuff, int bufferOffset, int bufferLength) throws JccfcFastDFSException;

    /**
     * 修改存储服务器的附加文件 (通过回调)
     *
     * @param appenderFileId 附加文件id
     * @param fileOffset      附加文件的偏移量
     * @param modify_size      修改的大小
     * @param callback         写数据回调对象
     * @return 0表示成功，!= 0表示错误(错误号)
     */
    Optional<Integer> modifyFile(String appenderFileId,long fileOffset, long modify_size, UploadCallback callback) throws JccfcFastDFSException;

    /**
     * 从存储服务器删除文件
     *
     * @param fileId 文件id(包括组名和文件名)
     * @return 0表示成功，!= 0表示错误(错误号)
     */
    Optional<Integer> deleteFile(String fileId) throws JccfcFastDFSException;

    /**
     * 从存储服务器截断大小为0的追加文件
     *
     * @param appenderFileId 附加文件id
     * @return 0表示成功，!= 0表示错误(错误号)
     */
    Optional<Integer> truncateFile(String appenderFileId) throws JccfcFastDFSException;

    /**
     * 从存储服务器截断追加文件
     *
     * @param appenderFileId    附加文件id
     * @param truncatedFileSize 截断文件大小
     * @return 0表示成功，!= 0表示错误(错误号)
     */
    Optional<Integer> truncateFile(String appenderFileId, long truncatedFileSize) throws JccfcFastDFSException;

    /**
     * 从存储服务器下载文件
     *
     * @param fileId 文件id(包括组名和文件名)
     * @return 文件内容字节数组er, 失败返回null
     */
    Optional<byte[]> downloadFile(String fileId) throws JccfcFastDFSException;

    /**
     * 从存储服务器下载文件
     *
     * @param fileId        文件id(包括组名和文件名)
     * @param fileOffset    文件的开始偏移量
     * @param downloadBytes 下载字节，从偏移量中保留的字节为0
     * @return 文件内容字节数组, 失败返回null
     */
    Optional<byte[]> downloadFile(String fileId, long fileOffset, long downloadBytes) throws JccfcFastDFSException;

    /**
     * 从存储服务器下载文件
     *
     * @param fileId        文件id(包括组名和文件名)
     * @param localFileName 本地的文件名
     * @return 0表示成功，!= 0表示错误(错误号)
     */
    Optional<Integer> downloadFile(String fileId, String localFileName) throws JccfcFastDFSException;
    /**
     * 从存储服务器下载文件
     *
     * @param fileId        文件id(包括组名和文件名)
     * @param fileOffset    文件的开始偏移量
     * @param downloadBytes 下载字节，从偏移量中保留的字节为0
     * @param localFileName 本地的文件名
     * @return 0表示成功，!= 0表示错误(错误号)
     */
    Optional<Integer> downloadFile(String fileId, long fileOffset, long downloadBytes, String localFileName) throws JccfcFastDFSException;

    /**
     * 从存储服务器下载文件
     *
     * @param fileId  文件id(包括组名和文件名)
     * @param callback 当数据到达时，回调对象将调用call .recv()
     * @return 0表示成功，!= 0表示错误(错误号)
     */
    Optional<Integer> downloadFile(String fileId, DownloadCallback callback) throws JccfcFastDFSException;
    /**
     * 从存储服务器下载文件
     *
     * @param fileId        文件id(包括组名和文件名)
     * @param fileOffset    文件的开始偏移量
     * @param downloadBytes 下载字节，从偏移量中保留的字节为0
     * @param callback       当数据到达时，回调对象将调用call .recv()
     * @return 0表示成功，!= 0表示错误(错误号)
     */
    Optional<Integer> downloadFile(String fileId, long fileOffset, long downloadBytes, DownloadCallback callback) throws JccfcFastDFSException;

    /**
     * 从存储服务器获取所有元数据项
     *
     * @param fileId 文件id(包括组名和文件名)
     * @return 元数据数组, 失败返回null
     */
    Optional<NameValuePair[]> getMetadata(String fileId) throws JccfcFastDFSException;

    /**
     * 设置元数据项
     *
     * @param fileId   文件id(包括组名和文件名)
     * @param metaList 元数据数组
     * @param opFlag   标志，可以是下列值之一: <br>
     *                  <ul><li> ProtoCommon.STORAGE_SET_METADATA_FLAG_OVERWRITE: overwrite,覆盖所有旧的元数据项</li></ul>
     *                  <ul><li> ProtoCommon.STORAGE_SET_METADATA_FLAG_MERGE: merage，当元数据项不存在时插入，否则更新它</li></ul>
     * @return 0表示成功，!= 0表示错误(错误号)
     */
    Optional<Integer> setMetadata(String fileId, NameValuePair[] metaList, byte opFlag) throws JccfcFastDFSException;

    /**
     * 从存储服务器获取文件信息
     *
     * @param fileId 文件id(包括组名和文件名)
     * @return FileInfo对象为成功，返回null为失败
     */
    Optional<FileInfo> queryFileInfo(String fileId) throws JccfcFastDFSException;

    /**
     * 从文件名获取文件信息解码
     *
     * @param fileId 文件id(包括组名和文件名)
     * @return FileInfo对象为成功，返回null为失败
     */
    Optional<FileInfo> getFileInfo(String fileId) throws JccfcFastDFSException;

    /**
     * 获取文件的绝对地址
     *
     * @param fileId 文件id(包括组名和文件名)
     * @return 成功返回绝对路径，否则返回空
     */
    Optional<String> getFileAbsolutePath(String fileId) throws JccfcFastDFSException;
}
